package com.cash.app.base

import android.widget.Toast
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import com.cash.app.application.ActivityLifecycleManager
import com.cash.app.application.MyApplication
import com.cash.app.custom.CommonLoading
import com.cash.app.net.NetResult
import com.cash.app.utils.TLog
import kotlinx.coroutines.CoroutineExceptionHandler
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext

abstract class BaseViewModel : ViewModel() {

    private var loading: CommonLoading? = null

    protected fun <T> launchRequest(
        request: suspend () -> NetResult<T>,
        onStart: () -> Unit = { },
        onSuccess: (T?) -> Unit = {},
        onError: (code: Int, message: String) -> Unit = { _, _ -> },
        onException: (code: Int, message: String) -> Unit = { _, _ -> }
    ) {

        val handler = CoroutineExceptionHandler { _, throwable ->
            TLog.e("Coroutine catch: $throwable", "BaseViewModel")
        }

        viewModelScope.launch(Dispatchers.Main.immediate + handler) {
            onStart()
            //showLoading()
            val result = withContext(Dispatchers.IO) {
                request()
            }
            when (result) {
                is NetResult.Success -> {
                    //hideLoading()
                    onSuccess(result.data)
                }

                is NetResult.Error -> {
                    onError(result.code, result.message)
                    handleError(result.code, result.message)
                }

                is NetResult.Exception -> {
                    onException(result.code, result.message)
                    handleError(result.code, result.message)
                }
            }
        }
    }

    private fun handleError(errorCode: Int, errorMessage: String) {
        //hideLoading()
        Toast.makeText(
            MyApplication.appContext, errorMessage, Toast.LENGTH_SHORT
        ).show()
    }

    private fun showLoading() {
        if (loading == null) {
            loading = CommonLoading.Builder(ActivityLifecycleManager.getSafeContext()).build()
        }
        loading!!.show()
    }

    private fun hideLoading() {
//        viewModelScope.launch {
//            delay(100)
//        }
        loading?.dismiss()
        loading = null
    }
}